#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <assert.h>

//父进程在轮询等待的过程中，还能处理其他事情
#define NUM 10
typedef void (*func_t)();//函数指针
func_t handlerTask[NUM];

//样例
void task1(){
  printf("handler task1\n");
}

void task2(){
  printf("handler task2\n");
}

void task3(){
  printf("handler task3\n");
}

void loadTask(){
  memset(handlerTask,0,sizeof(handlerTask));
  handlerTask[0] = task1;
  handlerTask[1] = task2;
  handlerTask[2] = task3;
}


//非阻塞等待，轮询等待
int main(){
  pid_t id = fork();
  //assert(id > 0);
  if(id == 0){
    //子进程
    int cnt = 5;
    while(cnt--){
      //printf("我是子进程：pid:%d,ppid:%d,cnt:%d\n",getpid(),getppid(),cnt);
      sleep(1);
    }
    exit(10);
  }else{
  //父进程
  loadTask();
    int status = 0;
    while(1){
      pid_t ret = waitpid(id,&status,WNOHANG);//wnohang :非阻塞等待，父进程检测的时候，子进程没有退出，立即返回

      if(ret == 0){
        //wait调用成功 && 子进程没有退出
        //子进程没有退出，我的waitpid也没有调用失败，仅仅是检测到了子进程没有退出
        printf("调用成功，但是子进程还在运行,父进程继续执行其他事务\n");
        for(int i = 0;handlerTask[i]!=NULL;i++){
          handlerTask[i]();//采用回调函数的方式，执行我们想让父进程在空闲的时候做的事情。
        }
      }else if(ret >0){
        //wait调用成功，子进程退出了
        printf("wait success,exit code:%d,sign:%d\n",(status>>8)&0xFF,status&0x7F);
        break;
      }else{
        //wait调用失败
        printf("waitpid call failed\n");
        break; 
      }
    sleep(1);
    }
  }


}
